import { useReducer, useState } from "react"

// 1. 简单计数器的状态和动作类型
interface CounterState {
  count: number
}

type CounterAction =
  | { type: "increment"; payload?: number }
  | { type: "decrement"; payload?: number }
  | { type: "reset"; payload?: number }

// 2. Reducer函数：根据当前状态和动作返回新状态
const counterReducer = (
  state: CounterState,
  action: CounterAction
): CounterState => {
  switch (action.type) {
    case "increment":
      return { count: state.count + (action.payload || 1) }
    case "decrement":
      return { count: state.count - (action.payload || 1) }
    case "reset":
      return { count: action.payload || 0 }
    default:
      return state
  }
}

// 3. 复杂例子：待办事项应用
interface TodoItem {
  id: number
  text: string
  completed: boolean
}

interface TodoState {
  todos: TodoItem[]
  todoCount: number
  completedCount: number
}

type TodoAction =
  | { type: "add"; payload: string }
  | { type: "toggle"; payload: number }
  | { type: "delete"; payload: number }
  | { type: "clear_completed" }

const todoReducer = (state: TodoState, action: TodoAction): TodoState => {
  let newTodo: TodoItem
  let updatedTodos: TodoItem[]
  let completedCount: number
  let filteredTodos: TodoItem[]
  let remainingCompletedCount: number
  let activeTodos: TodoItem[]

  switch (action.type) {
    case "add":
      if (!action.payload.trim()) return state

      newTodo = {
        id: Date.now(),
        text: action.payload,
        completed: false,
      }

      return {
        todos: [...state.todos, newTodo],
        todoCount: state.todoCount + 1,
        completedCount: state.completedCount,
      }

    case "toggle":
      updatedTodos = state.todos.map((todo) =>
        todo.id === action.payload
          ? { ...todo, completed: !todo.completed }
          : todo
      )

      completedCount = updatedTodos.filter((todo) => todo.completed).length

      return {
        todos: updatedTodos,
        todoCount: state.todoCount,
        completedCount,
      }

    case "delete":
      filteredTodos = state.todos.filter((todo) => todo.id !== action.payload)
      remainingCompletedCount = filteredTodos.filter(
        (todo) => todo.completed
      ).length

      return {
        todos: filteredTodos,
        todoCount: filteredTodos.length,
        completedCount: remainingCompletedCount,
      }

    case "clear_completed":
      activeTodos = state.todos.filter((todo) => !todo.completed)

      return {
        todos: activeTodos,
        todoCount: activeTodos.length,
        completedCount: 0,
      }

    default:
      return state
  }
}

// 主组件
const UseReducerDemo = () => {
  // 1. 简单计数器示例：使用useReducer
  const [counterState, counterDispatch] = useReducer(counterReducer, {
    count: 0,
  })

  // 2. 使用useState实现相同的计数器功能（用于比较）
  const [count, setCount] = useState(0)

  // 3. 复杂例子：待办事项
  const [todoState, todoDispatch] = useReducer(todoReducer, {
    todos: [],
    todoCount: 0,
    completedCount: 0,
  })

  const [newTodo, setNewTodo] = useState("")

  const handleAddTodo = () => {
    todoDispatch({ type: "add", payload: newTodo })
    setNewTodo("")
  }

  return (
    <div className="demo-section">
      <h2>useReducer Hook 面试题讲解</h2>

      <div className="card">
        <h3>1. 什么是 useReducer?</h3>
        <p>
          useReducer 是 React 的一个 Hook，它是 useState
          的替代方案，适用于复杂的状态逻辑。它接收一个 reducer 函数和初始状态，
          返回当前状态和 dispatch 函数，用于触发状态更新。
        </p>

        <div className="code-example">
          <code>
            const [state, dispatch] = useReducer(reducer, initialState); //
            reducer 函数格式 function reducer(state, action) {"{"}
            switch (action.type) {"{"}
            case 'increment': return {"{"}count: state.count + 1{"}"}; // 其他
            case... default: return state;
            {"}"}
            {"}"}
          </code>
        </div>
      </div>

      <div className="card">
        <h3>2. 常见面试问题: useReducer vs useState</h3>
        <p>
          <strong>useReducer 适合的场景:</strong>
        </p>
        <ul>
          <li>状态逻辑复杂，包含多个子值</li>
          <li>下一个状态依赖于前一个状态</li>
          <li>需要处理深层次的状态嵌套</li>
          <li>状态更新逻辑清晰可维护</li>
        </ul>

        <p>
          <strong>useState 适合的场景:</strong>
        </p>
        <ul>
          <li>简单的状态更新</li>
          <li>独立的状态变量</li>
          <li>不需要复杂逻辑判断的状态</li>
        </ul>

        <div className="flex-container">
          <div className="flex-item">
            <h4>使用 useReducer 的计数器:</h4>
            <p>
              当前计数: <strong>{counterState.count}</strong>
            </p>
            <button onClick={() => counterDispatch({ type: "increment" })}>
              加1
            </button>
            <button onClick={() => counterDispatch({ type: "decrement" })}>
              减1
            </button>
            <button
              onClick={() => counterDispatch({ type: "increment", payload: 5 })}
            >
              加5
            </button>
            <button onClick={() => counterDispatch({ type: "reset" })}>
              重置
            </button>
          </div>

          <div className="flex-item">
            <h4>使用 useState 的计数器:</h4>
            <p>
              当前计数: <strong>{count}</strong>
            </p>
            <button onClick={() => setCount(count + 1)}>加1</button>
            <button onClick={() => setCount(count - 1)}>减1</button>
            <button onClick={() => setCount(count + 5)}>加5</button>
            <button onClick={() => setCount(0)}>重置</button>
          </div>
        </div>
      </div>

      <div className="card">
        <h3>3. 使用场景: 复杂状态管理</h3>
        <p>
          useReducer
          特别适合管理包含多个子值的复杂状态，如表单、列表或具有多个操作的组件。
          以下是一个待办事项应用的例子:
        </p>

        <div className="example-output">
          <h4>待办事项应用</h4>
          <div>
            <input
              type="text"
              value={newTodo}
              onChange={(e) => setNewTodo(e.target.value)}
              placeholder="添加新待办事项..."
              style={{ marginRight: "10px", padding: "8px" }}
            />
            <button onClick={handleAddTodo}>添加</button>
            <button
              onClick={() => todoDispatch({ type: "clear_completed" })}
              disabled={todoState.completedCount === 0}
              style={{ marginLeft: "10px" }}
            >
              清除已完成
            </button>
          </div>

          <div style={{ marginTop: "15px" }}>
            <strong>统计: </strong>
            总计 {todoState.todoCount} 项， 已完成 {todoState.completedCount} 项
          </div>

          <ul style={{ listStyle: "none", padding: "10px 0" }}>
            {todoState.todos.map((todo) => (
              <li
                key={todo.id}
                style={{
                  margin: "8px 0",
                  padding: "8px",
                  backgroundColor: "#f5f5f5",
                  borderRadius: "4px",
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "space-between",
                }}
              >
                <div>
                  <input
                    type="checkbox"
                    checked={todo.completed}
                    onChange={() =>
                      todoDispatch({ type: "toggle", payload: todo.id })
                    }
                    style={{ marginRight: "10px" }}
                  />
                  <span
                    style={{
                      textDecoration: todo.completed ? "line-through" : "none",
                      color: todo.completed ? "#888" : "#333",
                    }}
                  >
                    {todo.text}
                  </span>
                </div>
                <button
                  onClick={() =>
                    todoDispatch({ type: "delete", payload: todo.id })
                  }
                >
                  删除
                </button>
              </li>
            ))}
          </ul>

          {todoState.todos.length === 0 && (
            <div
              style={{ textAlign: "center", padding: "20px", color: "#888" }}
            >
              暂无待办事项
            </div>
          )}
        </div>
      </div>

      <div className="card">
        <h3>4. 常见面试问题: 为什么要使用 Action Type?</h3>
        <p>
          在 useReducer 中，我们通常使用 action 对象，其中包含 type 字段和可选的
          payload。这种模式有几个好处:
        </p>
        <ul>
          <li>使代码更加可预测和可维护</li>
          <li>便于调试和跟踪状态变化</li>
          <li>遵循 Redux 和 Flux 架构的设计理念</li>
          <li>帮助团队成员理解和遵循统一的状态更新模式</li>
        </ul>

        <div className="code-example">
          <code>
            // 使用 action type 更新状态 dispatch(
            {"{ type: 'increment', payload: 5 }"}); // reducer 中处理不同类型的
            action function reducer(state, action) {"{"}
            switch (action.type) {"{"}
            case 'increment': return {"{"}count: state.count + action.payload
            {"}"}; case 'decrement': return {"{"}count: state.count -
            action.payload{"}"}; // ...
            {"}"}
            {"}"}
          </code>
        </div>
      </div>

      <div className="card">
        <h3>5. 常见面试问题: useReducer 与 Redux 的关系</h3>
        <p>useReducer 和 Redux 都基于 reducer 模式，但它们的用途和范围不同:</p>
        <table>
          <thead>
            <tr>
              <th>特性</th>
              <th>useReducer</th>
              <th>Redux</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>作用范围</td>
              <td>组件级状态管理</td>
              <td>全局应用状态管理</td>
            </tr>
            <tr>
              <td>复杂度</td>
              <td>较低，内置于 React</td>
              <td>较高，需要额外的库和样板代码</td>
            </tr>
            <tr>
              <td>中间件</td>
              <td>不支持内置中间件</td>
              <td>支持中间件 (如异步操作、日志等)</td>
            </tr>
            <tr>
              <td>开发工具</td>
              <td>有限的调试能力</td>
              <td>强大的开发者工具，如时间旅行调试</td>
            </tr>
            <tr>
              <td>状态共享</td>
              <td>需要结合 Context 使用</td>
              <td>原生支持跨组件状态共享</td>
            </tr>
          </tbody>
        </table>
      </div>

      <div className="card">
        <h3>6. 高级话题: 合并 useReducer 与 useContext</h3>
        <p>
          useReducer 通常与 useContext
          结合使用，实现轻量级的状态管理解决方案，类似于 Redux 但更加简洁。
        </p>
        <div className="code-example">
          <code>
            // 1. 创建 Context const TodoContext = createContext(); // 2. 创建
            Provider 组件 function TodoProvider({"{ children }"}) {"{"}
            const [state, dispatch] = useReducer(todoReducer, initialState);
            return ({"<TodoContext.Provider value={{state, dispatch}}>"}
            {"{children}"}
            {"</TodoContext.Provider>"}
            );
            {"}"}
            // 3. 在子组件中使用 function TodoItem() {"{"}
            const {"{ state, dispatch }"} = useContext(TodoContext); //
            现在可以使用 state 和 dispatch
            {"}"}
          </code>
        </div>
      </div>

      <div className="card">
        <h3>7. useReducer 面试核心要点</h3>
        <ul>
          <li>useReducer 适用于复杂状态逻辑和拥有多个子值的状态</li>
          <li>遵循 reducer 模式，确保状态更新的可预测性</li>
          <li>action 类型化使代码更易维护和调试</li>
          <li>可以与 useContext 结合，实现简单的状态管理系统</li>
          <li>相比于 useState，更适合处理相互依赖的状态更新</li>
          <li>reducer 函数应当是纯函数，无副作用</li>
          <li>对于简单的状态更新，useState 仍然是更好的选择</li>
        </ul>
      </div>
    </div>
  )
}

export default UseReducerDemo
